package com.dyna.web.tx.service.impl;

import com.dyna.core.exception.CustomException;
import com.dyna.cp.mybatis.domain.entity.DemoUser;
import com.dyna.cp.mybatis.mapper.DemoUserMapper;
import com.dyna.web.tx.service.TxService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Slf4j
@Service
public class TxServiceImpl implements TxService {

    @Resource
    private DemoUserMapper demoUserMapper;

    @Override
    public void normalTransactionalScene() {
        DemoUser demoUser = new DemoUser();
        demoUser.setName("test01");
        demoUserMapper.addUser(demoUser);
        this.addUser1();
        log.info("执行玩了....");
    }

    public void addUser1() {
        // test01中业务逻辑
        DemoUser demoUser = new DemoUser();
        demoUser.setName("test02");
        demoUserMapper.addUser(demoUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rollbackTransactionalScene() {
        DemoUser demoUser = new DemoUser();
        demoUser.setName("test01");
        demoUserMapper.addUser(demoUser);
        this.addUser1();
        throw new CustomException("回滚异常");
    }

    /**
     * rollbackTransactionalFailScene1中不加事务注解，但是addUser2中加事务
     * this.addUser2()中，因为是this调用的，@Transactional想要生效必须通过代理过来，this是不走代理的，所以会不生效
     */
    @Override
    public void rollbackTransactionalFailScene1() {
        DemoUser demoUser = new DemoUser();
        demoUser.setName("test01");
        demoUserMapper.addUser(demoUser);
//        this.addUser2();

        // 解决方案：获取代理对象并调用 addUser2
        TxService proxy = (TxService) AopContext.currentProxy();
        proxy.addUser2();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addUser2() {
        // test01中业务逻辑
        DemoUser demoUser = new DemoUser();
        demoUser.setName("test03");
        demoUserMapper.addUser(demoUser);
        throw new CustomException("回滚异常");
    }

}
